home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 2: CDPD 1
/
Almathera Ten on Ten - Disc 2: CDPD 1.iso
/
pd
/
276-300
/
294
/
dnet
/
amiga
/
client
/
getfiles.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-14
|
9KB
|
453 lines
/*
* GETFILES.C V1.30
*
* DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
*
*
* GETFILES [-Nnetid] [-dlocaldir] [-c] file/dir file/dir file/dir
*
* -Nnetid network identifier
*
* -dlocaldir local directory to place files
*
* -c Continue from where you left off before. Files that already
* exist on the local machine will not be re-transfered. This
* will also re-start in the middle of a file that was
* partially transfered previously.
*
* This command assumes the file(s) on both machines have not
* been modified since the first attempt. No other checking
* is done at the moment.
*/
#include "defs.h"
void main ARGS((int, char **));
typedef struct {
char Cmd;
char Str[128];
long Val;
} HDR;
extern int Enable_Abort;
char Buf[4096];
short ContMode;
char *NetId;
long LocalDirLock;
void *Chan;
void fail ARGS((int));
int CheckNoPath ARGS((char *));
int LostChannel ARGS((void));
void UnknownCmd ARGS((HDR *));
int GetFile ARGS((HDR *, int));
int GetDir ARGS((HDR *, int));
int WriteHeader ARGS((char, char *, long));
int ReadHeader ARGS((HDR *));
char *NSpaces ARGS((int));
int CheckBreak ARGS((void));
void ResetBreak ARGS((void));
int brk()
{
return(0);
}
void
main(ac,av)
int ac;
char *av[];
{
HDR Hdr;
short error;
onbreak(brk);
#ifndef LATTICE
Enable_Abort = 0;
#endif
printf("GetFiles V%s%s\n", VERSION, GETFILES_VERSION);
ResetBreak();
{
char *ldir = "";
FIB *fib = malloc(sizeof(FIB));
ac = DoOption(ac, av, "N%sd%sc", &NetId, &ldir, &ContMode);
if (ac <= 1) {
puts("GETFILES [-Nnetid -dlocaldir -c] remotefile/dir ...");
fail(22);
}
LocalDirLock = Lock(ldir, SHARED_LOCK);
if (!LocalDirLock && ldir[0]) { /* couldn't find it, try to make it */
if (LocalDirLock = (long)CreateDir(ldir)) {
UnLock(LocalDirLock);
LocalDirLock = Lock(ldir, SHARED_LOCK);
}
}
if (!LocalDirLock || !Examine(LocalDirLock, fib) || fib->fib_DirEntryType < 0) {
printf("Unable to CD or create local directory: \"%s\"\n", ldir);
fail(21);
}
}
Chan = DOpen(NetId, PORT_GFILECOPY, 126, -80);
if (!Chan) {
puts("Unable to connect");
fail(20);
}
error = WriteHeader('H', "Hello, getfiles client V1.30", 0);
if (error)
fail(LostChannel());
switch(ReadHeader(&Hdr)) {
case -1:
fail(LostChannel());
case 'H':
printf("%s\n", Hdr.Str);
break;
}
{
short i;
for (i = 1; i < ac; ++i) {
short error;
error = WriteHeader('G', av[i], 0);
if (error)
fail(LostChannel());
switch(ReadHeader(&Hdr)) {
case -1:
fail(LostChannel());
case 'N':
printf("Remote error on %s: %s\n", av[i], Hdr.Str);
break;
case 'F':
error = CheckNoPath(Hdr.Str);
if (!error) {
long olddir = (long)CurrentDir(LocalDirLock);
error = GetFile(&Hdr, 0);
CurrentDir(olddir);
}
break;
case 'D':
error = CheckNoPath(Hdr.Str);
if (!error) {
long olddir = (long)CurrentDir(LocalDirLock);
error = GetDir(&Hdr, 0);
CurrentDir(olddir);
}
break;
case 'S':
printf("Access Violation: %s\n", Hdr.Str);
break;
default:
UnknownCmd(&Hdr);
error = 1;
break;
}
if (error)
fail(error);
}
if (!error) {
error = WriteHeader('E', "bye", 0);
if (error)
fail(LostChannel());
}
}
fail(0);
}
void
fail(code)
{
if (Chan)
DClose(Chan);
if (LocalDirLock)
UnLock(LocalDirLock);
exit(code);
}
int
CheckNoPath(str)
char *str;
{
while (*str) {
if (*str == '/' || *str == ':') {
puts("SECURITY ALERT: Illegal path spec received");
return(40);
}
++str;
}
return(0);
}
int
LostChannel()
{
puts("DATA CHANNEL LOST");
return(10);
}
void
UnknownCmd(hdr)
HDR *hdr;
{
printf("UnRecognized command code: %02x\n", hdr->Cmd);
}
/*
* retrieve a file. If ContMode set and file exists, try to append to
* it.
*/
int
GetFile(hdr, stab)
HDR *hdr;
int stab;
{
long Fh = NULL;
long pos = 0;
short error = 0;
printf("%s%-20s ", NSpaces(stab), hdr->Str);
fflush(stdout);
if (ContMode) {
SetProtection(hdr->Str, 0); /* make sure it's r/w */
if (Fh = Open(hdr->Str, 1005)) { /* already exists */
long len;
Seek(Fh, 0L, 1);
len = Seek(Fh, 0L, 0); /* get length */
if (len > hdr->Val) {
Close(Fh);
printf("Cont Error, local file is larger than remote!: %s\n", hdr->Str);
puts("(not downloaded)");
return(0);
}
if (len == hdr->Val) {
Close(Fh);
if (error = WriteHeader('S', NULL, 0))
return(LostChannel());
puts("HAVE IT, SKIP");
return(0);
}
printf("(HAVE %ld/%ld) ", len, hdr->Val);
hdr->Val -= len; /* that much less */
pos = len; /* start at offset */
}
}
if (!Fh) {
Fh = Open(hdr->Str, 1006);
if (!Fh) {
error = WriteHeader('N', "open error", 0);
printf("Unable to open %s for output\n", hdr->Str);
if (error)
return(LostChannel());
return(1);
}
}
error = WriteHeader('Y', NULL, pos); /* yes, gimme gimme */
/*
* Retrieve the data
*/
if (!error) {
long left = hdr->Val;
long cnt = pos;
long total = pos + left;
while (left) {
long n = (left > sizeof(Buf)) ? sizeof(Buf) : left;
printf("%6ld/%6ld\23313D", cnt, total);
fflush(stdout);
if (DRead(Chan, Buf, n) != n) {
error = 5;
break;
}
if (CheckBreak()) {
error = 1;
break;
}
if (Write(Fh, Buf, n) != n) {
puts("Local Write failed!");
error = 6;
break;
}
left -= n;
cnt += n;
if (CheckBreak()) {
error = 1;
break;
}
}
printf("%6ld/%6ld %s", cnt, total, ((cnt == total) ? "OK" : "INCOMPLETE"));
}
Close(Fh);
puts("");
if (error) {
SetProtection(hdr->Str, 10); /* disallow reads! */
return(LostChannel());
}
return((int)error);
}
/*
* Retrieve a directory. Create it if necessary.
*/
int
GetDir(hdr, stab)
HDR *hdr;
int stab;
{
short error = 0;
long dirlock;
static HDR Hdr; /* note: static */
if (CheckBreak())
return(1);
printf("%s%-20s(DIR)\n", NSpaces(stab), hdr->Str);
dirlock = Lock(hdr->Str, SHARED_LOCK); /* try to lock directory */
if (!dirlock) {
if (dirlock = (long)CreateDir(hdr->Str)) {
UnLock(dirlock);
dirlock = Lock(hdr->Str, SHARED_LOCK);
}
}
if (!dirlock) {
error = WriteHeader('N', "couldn't create", 0);
printf("Unable to create local directory: %s\n", hdr->Str);
if (error)
return(LostChannel());
return(1);
}
error = WriteHeader('Y', NULL, 0); /* yes, gimme gimme */
while (!error) {
switch(ReadHeader(&Hdr)) {
case -1:
error = 1;
break;
case 'E': /* end of directory */
UnLock(dirlock);
return(0);
break;
case 'F':
error = CheckNoPath(Hdr.Str);
if (!error) {
long olddir = (long)CurrentDir(dirlock);
error = GetFile(&Hdr, stab + 4);
CurrentDir(olddir);
}
break;
case 'D':
error = CheckNoPath(Hdr.Str);
if (!error) {
long olddir = (long)CurrentDir(dirlock);
error = GetDir(&Hdr, stab + 4);
CurrentDir(olddir);
}
break;
case 'S':
printf("Access Violation: %s\n", Hdr.Str);
break;
case 'N':
printf("REMOTE ERROR: %s\n", Hdr.Str);
error = 10;
break;
default:
UnknownCmd(&Hdr);
error = 1;
break;
}
}
UnLock(dirlock);
return(LostChannel());
}
int
WriteHeader(c, str, len)
char c;
char *str;
long len;
{
ubyte sl;
if (str == NULL)
str = "";
sl = strlen(str);
if (DWrite(Chan, &c, 1) < 0)
return(1);
if (DWrite(Chan, &sl,1) < 0)
return(1);
if (DWrite(Chan, str, sl) != sl)
return(1);
if (DWrite(Chan, &len, 4) != 4)
return(1);
return(0);
}
int
ReadHeader(hdr)
HDR *hdr;
{
ubyte sl;
ubyte cmd;
hdr->Cmd = -1;
if (DRead(Chan, &cmd, 1) != 1)
return(-1);
if (DRead(Chan, &sl, 1) != 1)
return(-1);
if (sl >= sizeof(hdr->Str)) {
puts("Software error: received file name length too long");
return(-1);
}
if (DRead(Chan, hdr->Str, sl) != sl)
return(-1);
hdr->Str[sl] = 0;
if (DRead(Chan, &hdr->Val, 4) != 4)
return(-1);
hdr->Cmd = cmd;
return((int)hdr->Cmd);
}
char *
NSpaces(n)
int n;
{
static char Buf[128];
static short in = 0;
static short last;
if (in == 0) {
in = 1;
BSet(Buf, sizeof(Buf)-1, ' ');
}
Buf[last] = ' ';
if (n < 127)
Buf[n] = 0;
last = n;
return(Buf);
}
int
CheckBreak()
{
if (SetSignal(0,0) & (SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D)) {
puts("^C");
return(1);
}
return(0);
}
void
ResetBreak()
{
SetSignal(0, SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D);
}